package trb.complexshield.benchmarking;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import no.hrp.hvrc.property.PropertyOwner;

public class BenchmarkTriangles {

    public static final String TUBE_PATH = "C:\\Users\\tomrbryn.000\\Documents\\master\\project\\excel\\tubeTriangleData.xml";
    public static final File TUBE_FILE = new File(TUBE_PATH);
    public static final String SPHERE_PATH = "C:\\Users\\tomrbryn.000\\Documents\\master\\project\\excel\\sphereTriangleData.xml";
    public static final File SPHERE_FILE = new File(SPHERE_PATH);

    public static void main(String[] args) {
        benchmarkSphereTriangles();
        //benchmarkTubeTriangles();
        printTables(TUBE_FILE);
        printTables(SPHERE_FILE);
    }

    private static void printTables(File file) {
        printTables(BenchmarkAll.benchmarkOutputListFromString(
                BenchmarkAll.readStringFromFile(file)));
    }

    private static void printTables(List<BenchmarkOutput> tubeOutputs) {
        System.out.println(generateTable(tubeOutputs, (owner) ->
                ("" + ((BenchmarkOutput) owner).getErrorPerc() / 100f).replace(".", ",")));
        System.out.println(generateTable(tubeOutputs, (owner) -> {
            BenchmarkOutput output = (BenchmarkOutput) owner;
            return ("" + output.timeNano.get()/1E9).replace(".", ",");
        }));
    }

    public static void benchmarkSphereTriangles() {
        BenchmarkAll.Settings settings = new BenchmarkAll.Settings(false, true, false, 1, 2, new int[0]);
        int[] tubeDivisions = new int[10];
        for (int i=0; i<tubeDivisions.length; i++) {
            tubeDivisions[i] = 3 + i;
        }
        List<BenchmarkOutput> outputs = new ArrayList<>();
        outputs.addAll(BenchmarkAll.benchmarkSpheres(settings));
        BenchmarkAll.writeStringToFile(SPHERE_FILE, BenchmarkAll.benchmarkOutputListToString(outputs));
    }

    public static void benchmarkTubeTriangles() {
        BenchmarkAll.Settings settings = new BenchmarkAll.Settings(false, true, false, 1, 2, new int[0]);
        int[] tubeDivisions = new int[10];
        for (int i=0; i<tubeDivisions.length; i++) {
            tubeDivisions[i] = 3 + i;
        }
        List<BenchmarkOutput> outputs = new ArrayList<>();
        outputs.addAll(BenchmarkAll.benchmarkTubes(settings, tubeDivisions));
        BenchmarkAll.writeStringToFile(TUBE_FILE, BenchmarkAll.benchmarkOutputListToString(outputs));
    }

    public static String generateTable(List<BenchmarkOutput> outputs
            , Function<PropertyOwner, String> ownerPropertyToString) {

        Map<Integer, Map<String, String>> triangleCountShapeResultMap = new HashMap<>();
        Set<String> nameSet = new HashSet<>();
        for (BenchmarkOutput output : outputs) {
            Integer triangleCount = output.triangleCount.get();
            if (triangleCount > 0) {
                Map<String, String> shapeResultMap = triangleCountShapeResultMap.get(triangleCount);
                if (shapeResultMap == null) {
                    shapeResultMap = new HashMap<>();
                    triangleCountShapeResultMap.put(triangleCount, shapeResultMap);
                }
                String string = ownerPropertyToString.apply(output);
                if (string != null) {
                    shapeResultMap.put(output.name.get(), string);
                }
                nameSet.add(output.name.get());
            }
        }
        List<String> nameList = new ArrayList<>(nameSet);
        Collections.sort(nameList);

        ArrayList<Integer> sortedTriangleCounts = new ArrayList(triangleCountShapeResultMap.keySet());
        Collections.sort(sortedTriangleCounts);

        StringBuilder str = new StringBuilder();
        str.append("triangleCount ");
        for (String name : nameList) {
            str.append(name).append(" ");
        }
        str.append("\n");

        for (Integer triangleCount : sortedTriangleCounts) {
            str.append(triangleCount).append(" ");
            Map<String, String> shapeResultMap = triangleCountShapeResultMap.get(triangleCount);
            for (String shapeName : nameList) {
                str.append(shapeResultMap.get(shapeName)).append(" ");
            }
            str.append("\n");
        }
        return str.toString();
    }
}
